<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>three</title>
    <style>
        body {
            background-color: #bfe3dd;
            color: #000;
        }

        .input_video {
            top: 0;
            left: 0;
            position: fixed;
            transform: scale(1.5);
            transform-origin: 0%;
        }
        button{
            position: fixed;
            top:30%
        }
    </style>


    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/electroluxasset@1.0.5/mediapipe/holistic/camera_utils.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/electroluxasset@1.0.5/mediapipe/holistic/control_utils.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/electroluxasset@1.0.5/mediapipe/holistic/drawing_utils.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/electroluxasset@1.0.5/mediapipe/holistic/holistic.js" crossorigin="anonymous"></script>

    <script src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

    <script type="importmap">
    {
        "imports": {
        "three": "https://unpkg.com/three/build/three.module.js",
        "three/addons/": "https://unpkg.com/three/examples/jsm",
        "gui":"https://unpkg.com/three/examples/jsm/libs/lil-gui.module.min.js",
        "OrbitControls":"https://unpkg.com/three/examples/jsm/controls/OrbitControls.js",
            "FBXLoader":"https://unpkg.com/three/examples/jsm/loaders/FBXLoader"
        }
    }
    </script>
</head>

<body>

    <div class="canvas">
    </div>

    <div class="video1">


        <canvas id="canvas1" width="640" height="480"></canvas>

    </div>

    <video class="input_video"></video>
    <button onclick="">点哦</button>
    <!-- step1:引入插件 -->

    </head>


    <!-- 
        three  
        input mediapipe
        连接的方式可以在three加载好后将数据(模型)传输给mediapipe
    -->
    <script type="module">
        
        import * as THREE from 'three';
        import { GUI } from "gui";
        import { OrbitControls } from "OrbitControls"
        import { FBXLoader } from "FBXLoader"
        console.log(THREE)

        const clock = new THREE.Clock();
        let mixer
        let actions = []; //所有的动画数组
        // function initModel(url) {
        //     return new Promise((resolve) => {
        //         new FBXLoader().load(url, (object) => {
        //             mixer = new THREE.AnimationMixer(object);
        //             for (let i in object.animations) {
        //                 actions[i] = mixer.clipAction(object.animations[i]);
        //             }
        //             // action = mixer.clipAction( object.animations[ 16 ] );
        //             // console.log(object.animations)

        //             object.traverse((res) => {
        //                 // 贴图
        //                 if (res.type == "Mesh") {
        //                     const textureUrl = ["https://cdn.jsdelivr.net/npm/electroluxasset/model/front_css_example/sphere/ref.jpg", "https://cdn.jsdelivr.net/npm/electroluxasset/model/front_css_example/sphere/Control_Module_nmap.jpg", "https://cdn.jsdelivr.net/npm/electroluxasset/model/front_css_example/sphere/walker_color.jpg"]
        //                     for (let i in textureUrl) {
        //                         const textureLoader = new THREE.TextureLoader();
        //                         const textureNormal = textureLoader.load(
        //                             textureUrl[i]
        //                         );
        //                         res.material.map = textureNormal
        //                     }


        //                     // res.material.wireframe = true;

        //                 }

        //             });
        //             resolve(object);
        //         });
        //     });
        // }
        // let model = await initModel("https://cdn.jsdelivr.net/npm/electroluxasset/model/front_css_example/sphere/1.fbx");
        // // model.setAnimation( actions[0].name );
        // model.scale.set(0.25, 0.25, 0.25);

        // console.log(GUI)
        class threeInit {
            constructor(param) {
                this.param = {
                    x: 0,
                    y: 0,
                    z: 0
                }
                this.status = 16
                this.initScene()
                this.initLight()
                this.initObject()
                this.initCamera()
            }
            // 初始化物体
            initObject() {
                //材质
                let material = new THREE.MeshLambertMaterial({
                    color: 0x05c5cf4
                });
                let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
                this.mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
                this.mesh.position.set(this.param.x, this.param.y, this.param.z)
                this.mesh.scale.set(0.6,0.6,0.6)
                // this.scene.add(this.mesh)
                // this.mesh = model
                this.scene.add(this.mesh)
            }
            initScene() {
                this.scene = new THREE.Scene()
            }
            initLight() {
                let pointLight = new THREE.PointLight(0xffffff); //创建一个白色的点光源
                pointLight.position.set(0, 0, 150);
                this.scene.add(pointLight);
                let ambient = new THREE.AmbientLight(0xffffff, 1);
                
                this.scene.add(ambient);
                //                 const skyColor = 0xB1E1FF;  // bleu
                //   const groundColor = 0xB97A20;  // orange brun
                //   const intensity = 2;
                //                 const light = new THREE.HemisphereLight(skyColor, groundColor, intensity);
                //                 this.scene.add(light);
            }
            initCamera() {
                this.width = 1680; //canvas画布宽度
                this.height = 1200; //canvas画布高度
                let k = this.width / this.height; //canvas画布宽高比
                //三维场景显示范围控制系数，系数越大，显示的范围越大
                //创建相机对象
                this.camera = new THREE.PerspectiveCamera(30, k, 20, 1000);
                this.camera.position.set(300, 600, 300); //设置相机位置
                let v1 = new THREE.Vector3(0, 0, 0)
                this.camera.lookAt(v1); //设置相机方向(指向的场景对象)
            }
            initGui(status) {

                //1.设置基本属性
                let gui = new GUI();
                gui.domElement.classList.add();
                gui.domElement.style.cssText = "position:absolute;top:0px;right:0px;";
                // 2.等于params.x的属性跟mesh.position.y绑定
                //-3 到 3 每一次0.01  mesh.position.x
                gui.add(this.param, 'x', -3, 100, 0.01)
                    .onChange(() => {
                        this.mesh.position.x = this.param.x;
                    }).name('x的位置')

                gui.add(this.param, 'y', -3, 100, 0.01)
                    .onChange(() => {
                        this.mesh.position.y = this.param.y;
                    }).name('y的位置(上下)')

                gui.add(this.param, 'z', -3, 100, 0.01)
                    .onChange(() => {
                        this.mesh.position.z = this.param.z;
                    }).name('z的位置')
                // gui.add(params, 'wireframe', [true, false])
                //     .onChange(function () {
                //         material.wireframe = params.wireframe;
                //     }).name('设置线框')


                // // gui.add(material, 'wireframe').name('设置线框')
                // // gui.add(params,'background').name('设置天空')
                // //gui.addColor
                // gui.addColor(params, 'color')
                //     .onChange(function () {
                //         material.color.set(params.color);
                //     });

                // //2.重要：实现切换天空的效果
                // gui.add(params, 'background', ["sky", "home"])
                //     .onChange(function () {
                //         initskyboxsun25deg(params.background);
                //     }).name("切换天空");
            }
            initSkyBox() {

                const starUrls = [
                    ("https://cdn.jsdelivr.net/npm/electroluxasset/skybox/skyboxsun25deg/px.jpg"), // right
                    ("https://cdn.jsdelivr.net/npm/electroluxasset/skybox/skyboxsun25deg/nx.jpg"), // left
                    ("https://cdn.jsdelivr.net/npm/electroluxasset/skybox/skyboxsun25deg/py.jpg"), // top
                    ("https://cdn.jsdelivr.net/npm/electroluxasset/skybox/skyboxsun25deg/ny.jpg"), // bottom
                    ("https://cdn.jsdelivr.net/npm/electroluxasset/skybox/skyboxsun25deg/pz.jpg"), // back
                    ("https://cdn.jsdelivr.net/npm/electroluxasset/skybox/skyboxsun25deg/nz.jpg"), // front
                ];
                this.scene.background = new THREE.CubeTextureLoader().load(starUrls);


            }
            changeAction(status) {
                this.status = status
                for (var j = 0; j < actions.length; j++) {
                    if (j == status) {
                        actions[j].play();
                    }
                    else {
                        actions[j].stop();
                    }
                }

            }

            initRender(status) {

                let v1 = new THREE.Vector3(0, 0, 0)
                // let renderer = new THREE.WebGLRenderer();
                let renderer = new THREE.WebGLRenderer({ alpha: true });
                renderer.setSize(this.width, this.height);//设置渲染区域尺寸

                // 添加控制器
                let control = new OrbitControls(this.camera, renderer.domElement);
                control.target = v1 //设置相机方向(指向的场景对象)
                control.update();

                // renderer.setClearColor(0xb9d3ff, 1);
                // 渲染函数
                let render = () => {
                    // console.log(actions)
                    let status = this.status
                    // actions[status]?.play();
                    const delta = clock.getDelta();
                    if (mixer) mixer.update(delta);
                    control.update();
                    // this.mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
                    renderer.render(this.scene, this.camera);//执行渲染操作
                    // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
                    requestAnimationFrame(render);//请求再次执行渲染函数render，渲染下一帧
                }
                render(status);
                return renderer
            }


        }

        let three = new threeInit()
        // three.initGui(1)

        // three.initSkyBox()
        let status = 16

        document.querySelector('.canvas').appendChild(three.initRender().domElement);
    
        document.querySelector("button").addEventListener('click', () => {
            // var actions =actions
            main(three.mesh, actions)

        })
    </script>



    <script defer>

        function main(model, actions) {

            console.log(model, actions)
            let loganHandle = {
                prev: {
                    x: null,
                    y: null
                },
                next: {
                    x: null,
                    y: null
                }
            }
            let distance = {
                x_distance: null,
                y_distance: null,
                allDistance: null
            }

            // 求x y 移动的距离
            let loganHandleFn = (val) => {
                val.x = val.x*100
                val.y = val.y*100
                // 一开始的数据
                if (!loganHandle.prev.x && !loganHandle.next.x) {
                    loganHandle.prev = JSON.parse(JSON.stringify(val))
                    return
                }
                // 之后的数据
                if (loganHandle.prev.x && !loganHandle.next.x) {
                    loganHandle.next = JSON.parse(JSON.stringify(loganHandle.prev))
                    loganHandle.prev = JSON.parse(JSON.stringify(val))
                }
                // 更新数据
                if (loganHandle.prev.x && loganHandle.next.x) {
                    loganHandle.prev = JSON.parse(JSON.stringify(loganHandle.next))
                    loganHandle.next = JSON.parse(JSON.stringify(val))
                }
                if (loganHandle.prev.x && loganHandle.next.x) {
                    let x_distance = Math.pow((loganHandle.prev.x - loganHandle.next.x), 2)
                    let y_distance = Math.pow((loganHandle.prev.y - loganHandle.next.y), 2)
                    // console.log("笛卡尔距离：",x_distance,y_distance,Math.log2(x_distance+y_distance))
                    if (Math.log2(x_distance + y_distance)) {
                        // console.log("笛卡尔距离：",x_distance,y_distance,Math.log2(x_distance+y_distance))
                        distance.allDistance = Math.log2(x_distance + y_distance)

                    }
                    distance.x_distance = Math.log2(x_distance)
                    distance.y_distance = Math.log2(y_distance)
                }
            }


            const videoElement = document.getElementsByClassName('input_video')[0];

            function onResults(results) {
                // console.log(results?.poseLandmarks[16])
                try{
                    let thumb = results?.leftHandLandmarks[4]
                    let secondThumb = results?.leftHandLandmarks[8]
                    let distance_tempX = Math.pow((thumb.x - secondThumb.x), 2)
                    let distance_tempY = Math.pow((thumb.y - secondThumb.y), 2)
                    let distance_tempZ = Math.pow((thumb.z - secondThumb.z), 2)
                    let distance_thumb= Math.pow((distance_tempX + distance_tempY + distance_tempZ), 0.5)
                    // console.log(distance)


                    let scale  = distance_thumb
                    // 实现缩放
                    model.scale.set(scale*6,scale*6, scale*6);
                    
                    
                    loganHandleFn({
                        x:thumb.x,
                        y:thumb.y
                    })
                    // 实现旋转
                    // 实现平移

                    console.log(distance,loganHandle)
                    if (distance.x_distance > 0.1) {
                            // console.log("横着走")
                            // speakbot.speak("横着走")
                            // window.scrollBy(document.body.clientWidth * (loganHandle.prev.x - loganHandle.next.x) / 1000, 0)
                            // model.position.z = model.position.z + (loganHandle.prev.x - loganHandle.next.x) /2
                        model.rotateY( (loganHandle.prev.x - loganHandle.next.x) /10);
                    }
                    if (distance.y_distance > 0.1) {
                        // console.log("竖着走")
                        // speakbot.speak("竖着走")
                        model.position.y = model.position.y + (loganHandle.prev.y - loganHandle.next.y) *4
                        // window.scrollBy(0, document.body.clientHeight * (loganHandle.prev.y - loganHandle.next.y) / 1000)
                    }
                
                }catch{

                }
                
            }

            const holistic = new Holistic({
                locateFile: (file) => {
                    console.log(file, "file")
                    return `https://cdn.jsdelivr.net/npm/electroluxasset@1.0.5/mediapipe/holistic/locate/${file}`;
                }
            });
            holistic.setOptions({
                modelComplexity: 1,
                smoothLandmarks: true,
                enableSegmentation: true,
                smoothSegmentation: true,
                refineFaceLandmarks: true,
                minDetectionConfidence: 0.5,
                minTrackingConfidence: 0.5
            });
            holistic.onResults(onResults);

            const camera = new Camera(videoElement, {
                onFrame: async () => {
                    await holistic.send({ image: videoElement });
                },
                width: 200,
                height: 190
            });

            camera.start();


            // if (Math.log2(diff_x_distance + diff_y_distance)) {

            //     diff_distance = (Math.log2(diff_x_distance + diff_y_distance))/50
            // }
            // if(diff_distance>0.6 || diff_distance<0.5){
            //     model.scale.set(diff_distance,diff_distance, diff_distance);
            // }


        }




        // main()
    </script>
</body>

</html>